package com.utils;

import com.enums.QrcodeType;
import com.framework.security.BlowFish;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

/**
 * 二维码工具
 *
 */
public class QrcodeUtils {
	
	/**
	 * 
	 * @param encode 是否使用加密
	 * @param qrcodeType 二维码类型
	 * @param map 数据模型
	 * @return
	 */
	public static String preEncoder(boolean encode,QrcodeType qrcodeType,Map<String,Object> map){
		StringBuffer msg=new StringBuffer("cmd:"+qrcodeType.getValue());
		StringBuffer code=new StringBuffer();
		String codeValue="";
		if (qrcodeType.equals(QrcodeType.DEVICE)) {
			code.append(map.get("id")).append("-");
			String deviceCode=map.get("deviceCode").toString();
			deviceCode=deviceCode.lastIndexOf("-")!=-1?deviceCode.replace("-", "##"):deviceCode;
			code.append(deviceCode).append("-");
			String factoryCode=map.get("factoryCode").toString();
			factoryCode=factoryCode.lastIndexOf("-")!=-1?factoryCode.replace("-", "##"):factoryCode;
			code.append(factoryCode).append("-")
			.append(map.get("deviceTypeId")).append("-")
			.append(map.get("deviceModelId"));
			deviceCode=null;
			factoryCode=null;
		}else if (qrcodeType.equals(QrcodeType.OUTADDR)) {
			code.append(map.get("url"));
		}
		msg.append(",encode:");
		if (encode) {
			msg.append(1);
			codeValue=BlowFish.pushEncode(code.toString());
		}else{
			msg.append(0);
			codeValue=code.toString();
		}
		msg.append(",code:").append(codeValue);
		code=null;
		codeValue=null;
		return msg.toString();
	}

    /**
     *  生成二维码
     * @param encode 是否需要加密
     * @param type 	生成图片的类型，0是二维码，1是条码，默认是二维码
	 * @param msg   二维码信息
     * @return BufferedImage
     */
    public static BufferedImage createQrcode(boolean encode,int type,String msg){
        BufferedImage image =  null;

        try {

            if(encode){
                msg = BlowFish.pushEncode(msg);
            }
            HashMap<EncodeHintType, String> hints = new HashMap<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
			BitMatrix bitMatrix = null;
			if(type==1){
				int qrcodeWidth = 250;
				int qrcodeHeight = 50;
				//EAN_13
//				boolean flag = checkStandardUPCEANChecksum(msg);
//				if(flag){
//					bitMatrix = new MultiFormatWriter().encode(msg, BarcodeFormat.EAN_13, qrcodeWidth, qrcodeHeight, hints);
//				}
				bitMatrix = new MultiFormatWriter().encode(msg, BarcodeFormat.CODE_39, qrcodeWidth, qrcodeHeight,hints);
			}else{
				int qrcodeWidth = 400;
				int qrcodeHeight = 400;
				bitMatrix = new MultiFormatWriter().encode(msg, BarcodeFormat.QR_CODE, qrcodeWidth, qrcodeHeight,hints);
			}

            //image = new BufferedImage(qrcodeWidth, qrcodeHeight, BufferedImage.TYPE_INT_RGB);
			image = MatrixToImageWriter.toBufferedImage(bitMatrix);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return image;
    }

	/**
	 * 	解析二维码信息,目前不支持条码解析
	 * @param filePath 二维码图片路径
	 * @return  String
	 */
    public static String decodeQrcode(String filePath) {
        String retStr = "";
        if ("".equalsIgnoreCase(filePath) && filePath.length() == 0) {
            return "图片路径为空!";
        }
        try {
            BufferedImage bufferedImage = ImageIO.read(new FileInputStream(filePath));
            LuminanceSource source = new BufferedImageLuminanceSource(bufferedImage);
            Binarizer binarizer = new HybridBinarizer(source);
            BinaryBitmap bitmap = new BinaryBitmap(binarizer);
            HashMap<DecodeHintType, Object> hintTypeObjectHashMap = new HashMap<>();
            hintTypeObjectHashMap.put(DecodeHintType.CHARACTER_SET, "UTF-8");
			hintTypeObjectHashMap.put(DecodeHintType.PURE_BARCODE,true);
            Result result = new MultiFormatReader().decode(bitmap, hintTypeObjectHashMap);
            retStr = result.getText();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return retStr;
    }

	/**
	 * 	检查内容是否可以生成条形码，可以返回true，不可以放false
	 * @param s
	 * @return
	 * @throws FormatException
	 */
	public static boolean checkStandardUPCEANChecksum(CharSequence s) throws FormatException {
		int length = s.length();
		if (length == 0) {
			return false;
		}

		int sum = 0;
		for (int i = length - 2; i >= 0; i -= 2) {
			int digit = (int) s.charAt(i) - (int) '0';
			if (digit < 0 || digit > 9) {
				throw FormatException.getFormatInstance();
			}
			sum += digit;
		}
		sum *= 3;
		for (int i = length - 1; i >= 0; i -= 2) {
			int digit = (int) s.charAt(i) - (int) '0';
			if (digit < 0 || digit > 9) {
				throw FormatException.getFormatInstance();
			}
			sum += digit;
		}
		return sum % 10 == 0;
	}


	public static void main (String[] args) throws IOException {
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("id", 17);
		map.put("orderNo", "OD1234564");
		String msg = GsonUtils.toJson(map);
		msg="4009026725726";

		//BufferedImage bufferedImage = createQrcode(false,0,msg);
		MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
		HashMap<EncodeHintType, String> hints = new HashMap<EncodeHintType, String>();
		hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
		BitMatrix bitMatrix = null;
		try {
			bitMatrix = multiFormatWriter.encode(msg, BarcodeFormat.CODE_39, 400, 50,hints);
		File file1 = new File("F:/","abc.jpg");
		MatrixToImageWriter.writeToFile(bitMatrix, "jpg", file1);
		} catch (WriterException e) {
			e.printStackTrace();
		}
	}

}
